package com.demo.order.listener;

import com.alibaba.fastjson.JSON;
import com.demo.order.service.SeckillOrderService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * 秒杀订单消息监听器
 * 处理来自RabbitMQ的秒杀订单消息
 */
@Slf4j
@Component
public class SeckillOrderListener {

    @Autowired
    private SeckillOrderService seckillOrderService;

    /**
     * 监听秒杀订单消息
     * @param message 消息内容
     * @param channel 消息通道
     * @param amqpMessage AMQP消息对象
     */
    @RabbitListener(queues = "seckill.queue")
    public void handleSeckillOrder(String message, Channel channel, Message amqpMessage) {
        long deliveryTag = amqpMessage.getMessageProperties().getDeliveryTag();
        log.info("接收到秒杀订单消息: {}, deliveryTag: {}", message, deliveryTag);

        try {
            // 解析消息
            Map<String, Object> messageData = JSON.parseObject(message, Map.class);
            Long userId = Long.valueOf(messageData.get("userId").toString());
            Long productId = Long.valueOf(messageData.get("productId").toString());
            Integer quantity = Integer.valueOf(messageData.get("quantity").toString());
            String messageId = (String) messageData.get("messageId");

            log.info("开始处理秒杀订单，userId: {}, productId: {}, quantity: {}, messageId: {}", 
                    userId, productId, quantity, messageId);

            // 创建订单
            Map<String, Object> result = seckillOrderService.createSeckillOrder(userId, productId, quantity, messageId);
            
            if ((Boolean) result.get("success")) {
                log.info("秒杀订单处理成功: {}", result.get("message"));
                // 手动确认消息
                channel.basicAck(deliveryTag, false);
            } else {
                log.error("秒杀订单处理失败: {}", result.get("message"));
                // 拒绝消息，不重新入队（避免无限重试）
                channel.basicNack(deliveryTag, false, false);
            }

        } catch (Exception e) {
            log.error("处理秒杀订单消息异常，message: {}, deliveryTag: {}", message, deliveryTag, e);
            try {
                // 异常情况下拒绝消息，不重新入队
                channel.basicNack(deliveryTag, false, false);
            } catch (IOException ioException) {
                log.error("拒绝消息失败", ioException);
            }
        }
    }

    /**
     * 监听死信队列消息
     * 处理秒杀失败或超时的消息
     * @param message 消息内容
     * @param channel 消息通道
     * @param amqpMessage AMQP消息对象
     */
    @RabbitListener(queues = "seckill.dlx.queue")
    public void handleSeckillDeadLetter(String message, Channel channel, Message amqpMessage) {
        long deliveryTag = amqpMessage.getMessageProperties().getDeliveryTag();
        log.warn("接收到秒杀死信消息: {}, deliveryTag: {}", message, deliveryTag);

        try {
            // 解析消息
            Map<String, Object> messageData = JSON.parseObject(message, Map.class);
            Long userId = Long.valueOf(messageData.get("userId").toString());
            Long productId = Long.valueOf(messageData.get("productId").toString());
            Integer quantity = Integer.valueOf(messageData.get("quantity").toString());
            String messageId = (String) messageData.get("messageId");

            log.warn("秒杀订单超时或失败，userId: {}, productId: {}, quantity: {}, messageId: {}", 
                    userId, productId, quantity, messageId);

            // 这里可以进行一些补偿操作，比如记录失败日志、发送通知等
            // 由于订单已经超时，通常不需要特殊处理，只需要记录日志
            
            // 确认死信消息
            channel.basicAck(deliveryTag, false);
            
        } catch (Exception e) {
            log.error("处理死信消息异常，message: {}, deliveryTag: {}", message, deliveryTag, e);
            try {
                // 确认消息，避免死信消息无限循环
                channel.basicAck(deliveryTag, false);
            } catch (IOException ioException) {
                log.error("确认死信消息失败", ioException);
            }
        }
    }
}